package boot;

import Config.RegistryConfig;
import Config.RpcConfig;
import Constant.RpcConstant;
import Utils.ConfigUtil;
import lombok.extern.slf4j.Slf4j;
import register.Registry;
import register.RegistryFactory;

/**
 * Rpc 框架启动类，负责全局配置的初始化与管理
 */
@Slf4j
public class RpcApplication {

    /** 全局唯一配置对象（单例，volatile 保证可见性） */
    private static volatile RpcConfig rpcConfig;

    /**
     * 使用自定义配置初始化 Rpc 框架
     * @param newRpcConfig 用户自定义的配置对象
     */
    public static void init(RpcConfig newRpcConfig) {
        // 初始化全局配置
        rpcConfig = newRpcConfig;
        log.info("Rpc 框架初始化完成，启动时读取的全局配置对象: {}", newRpcConfig);

        // 初始化注册中心
        RegistryConfig registryConfig = rpcConfig.getRegistryConfig();
        Registry registry = RegistryFactory.getInstance(registryConfig.getRegistry());
        registry.init(registryConfig);
        log.info("注册中心初始化完成，注册中心对象: {}", registryConfig);

        // JVM 关闭前自动下线服务节点
        Runtime.getRuntime().addShutdownHook(new Thread(registry::destory));
    }

    /**
     * 默认初始化方式：加载配置文件并初始化全局唯一配置对象
     */
    public static void init() {
        RpcConfig newRpcConfig;
        try {
            // 加载配置文件
            newRpcConfig = ConfigUtil.loadConfig(RpcConfig.class, RpcConstant.RPC_COFIG_PREFIX);
        } catch (Exception e) {
            log.info("加载配置文件时出现异常，使用默认配置。");
            // 读取默认配置
            newRpcConfig = new RpcConfig();
        }
        init(newRpcConfig);
    }

    /**
     * 获取全局配置对象（双重检查锁定单例模式）
     * @return RpcConfig 全局配置对象
     */
    public static RpcConfig getRpcConfig() {
        if (rpcConfig == null) {
            synchronized (RpcApplication.class) {
                if (rpcConfig == null) {
                    init();
                }
            }
        }
        return rpcConfig;
    }
}
